import 'dart:typed_data';

import 'package:binary/binary.dart';
import 'package:inmotion_protocol/base/vehicle_data.dart';
import 'package:inmotion_protocol/common/compact.dart';
import 'package:inmotion_protocol/common/exceptions.dart';
import 'package:inmotion_protocol/common/mode.dart';
import 'package:inmotion_protocol/common/product_model.dart';
import 'package:inmotion_protocol/common/product_version.dart';
import 'package:inmotion_protocol/lorin/bean/base/real_time_info.dart';
import 'package:inmotion_protocol/lorin/bean/base/vehicle_real_time_info.dart';
import 'package:inmotion_protocol/lorin/bean/euc/euc_real_time_data.dart';
import 'package:inmotion_protocol/lorin/bean/euc/p6/p6_vehicle_real_time_info.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

class AllP6RealTimeData
    extends AllRealTimeData<P6RealTimeInfo, P6RealTimeState, P6RealTimeError> {
  AllP6RealTimeData(P6RealTimeInfo realTimeInfo, P6RealTimeState realTimeState,
      P6RealTimeError realTimeError)
      : super(realTimeInfo, realTimeState, realTimeError);
}

class P6VehicleSynthesizeRealTimeInfo extends VehicleSynthesizeRealTimeInfo<P6VehicleRealTimeInfo, P6RealTimeState, P6RealTimeError> {
  P6VehicleSynthesizeRealTimeInfo(P6VehicleRealTimeInfo commonVehicleRealTimeInfo, P6RealTimeState realTimeState, P6RealTimeError realTimeError) : super(commonVehicleRealTimeInfo, realTimeState, realTimeError);
}

/// 实时信息
class P6RealTimeInfo extends EucRealTimeInfo {
  Int16 chargeVoltage = Int16.zero; // 充电电压
  Int16 chargeCurrent = Int16.zero; // 充电电流
  Int16 acce = Int16.zero; // 加速度
  Uint16 tirePressure = Uint16.zero; // 轮胎压力
  Uint16 rtPhaseCurrentLimit = Uint16.zero; // 实时相电流限制
  Int16 batteryMaxCellTemp = Int16.zero; // 电池电芯最高温度
  Int16 batteryMaxBMSTemp = Int16.zero; // 电池BMS最高温度
  Uint8 lampBrightness = Uint8.zero; // 灯光亮度
  Uint8 lteSingle = Uint8.zero; // LTE信号强度 0: 无信号 1:1格 2:2格 3:3格 4:4格

  Uint16 overSpeedTiltBackThreshold = Uint16.zero;
  Uint16 overSpeedWarningThreshold = Uint16.zero;
  Uint16 overOutputTiltBackThreshold = Uint16.zero;
  Uint16 overOutputWarningThreshold = Uint16.zero;
  Uint16 overBusCurrentTiltBackThreshold = Uint16.zero;
  Uint16 overBusCurrentWarningThreshold = Uint16.zero;

  P6RealTimeInfo(super.model, super.version);

  @override
  void initCompact() {
    compact = _DefaultP6RealTimeInfo();
  }

  @override
  String toString() {
    String compactType = compact.runtimeType.toString();
    return 'P6RealTimeInfo{compact:$compactType, voltage: $voltage, current: $current, chargeVoltage: $chargeVoltage, chargeCurrent: $chargeCurrent, '
        'speed: $speed, acce: $acce, torque: $torque, outputRate: $outputRate, batteryOutputPower: $batteryOutputPower, motorOutputPower: $motorOutputPower, '
        'pitchAngle: $pitchAngle, rollAngle: $rollAngle, pitchAimAngle: $pitchAimAngle, speedingBrakingAngle: $speedingBrakingAngle, mileage: $mileage, '
        'tirePressure: $tirePressure, batteryLevel: $batteryLevel, batteryLevelForRide: $batteryLevelForRide, estimatedTotalMileage: $estimatedTotalMileage, '
        'remainderRange: $remainderRange, dynamicSpeedLimit: $dynamicSpeedLimit, mosTemp: $mosTemp, motorTemp: $motorTemp, batteryTemp: $batteryTemp, '
        'boardTemp: $boardTemp, cpuTemp: $cpuTemp, imuTemp: $imuTemp, batteryMaxCellTemp: $batteryMaxCellTemp, batteryMaxBMSTemp: $batteryMaxBMSTemp, '
        'lampTemp: $lampTemp, brightness: $brightness, lampBrightness: $lampBrightness, lteSingle: $lteSingle}';
  }
}

class _DefaultP6RealTimeInfo extends Compact<P6RealTimeInfo> {
  @override
  void fromBytes(P6RealTimeInfo output, Uint8ClampedList bytes, int offset) {
    if (bytes.length < offset + output.length()) {
      return;
    }
    output.voltage = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.current = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.chargeVoltage = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.chargeCurrent = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speed = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.acce = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.torque = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.outputRate = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.batteryOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.motorOutputPower = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.rollAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.pitchAimAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.speedingBrakingAngle = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.mileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.tirePressure = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;

    offset += 2; // 保留

    output.batteryLevel = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.batteryLevelForRide = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.estimatedTotalMileage = ByteUtil.bytes2Uint16Le(bytes, offset);
    output.remainderRange = Uint16(((output.batteryLevelForRide.value / 10000) *
            output.estimatedTotalMileage.value)
        .toInt());
    offset += 2;
    output.overSpeedTiltBackThreshold = ByteUtil.bytes2Uint16Le(bytes, offset);
    output.dynamicSpeedLimit = output.overSpeedTiltBackThreshold;
    offset += 2;
    output.overSpeedWarningThreshold = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overOutputTiltBackThreshold = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overOutputWarningThreshold = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overBusCurrentTiltBackThreshold =
        ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.overBusCurrentWarningThreshold =
        ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.rtPhaseCurrentLimit = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;

    offset += 4; // 保留

    output.mosTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.motorTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.batteryTemp =
        ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.boardTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.cpuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.imuTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.batteryMaxCellTemp =
        ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.batteryMaxBMSTemp =
        ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.lampTemp = ByteUtil.toInt16(ByteUtil.toInt8Int(bytes[offset]) + 80);
    offset += 1;
    output.brightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset += 1;
    output.lampBrightness = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset += 1;
    output.lteSingle = ByteUtil.bytes2Uint8Le(bytes, offset);
    offset += 1;

    offset += 4; // 保留
  }

  @override
  int length() {
    return 74;
  }
}

/// 实时状态
class P6RealTimeState extends EucRealTimeState {
  P6RealTimeState(ProductModel model, VersionWrapper version)
      : super(model, version);

  Uint32 chargePortDetect = Uint32.zero;
  ChargePort chargePort = ChargePort.none; // 充电口状态
  Uint4 chargePortOn = Uint4.zero; // 充电口状态
  Uint4 dcPortDetect = Uint4.zero; // 备用电池状态
  Uint4 dcOutputEnable = Uint4.zero; // 直流输出状态
  Uint4 decorativeLight = Uint4.zero; // 装饰灯状态
  Uint4 fanWorkState = Uint4.zero; // 风扇工作状态

  @override
  void initCompact() {
    compact = _DefaultP6RealTimeState();
  }
}

enum ChargePort {
  none, // 无任何设备接入
  plugged, // 充电器接入
  backupBattery, // 备用电池接入
  other, // 另一台车的直流出口接入
  undefined, // 不能识别的设备接入
}

class _DefaultP6RealTimeState extends Compact<P6RealTimeState> {
  @override
  void fromBytes(P6RealTimeState output, Uint8ClampedList bytes, int offset) {
    // 3bit
    output.pcModeValue =
        ByteUtil.toUint32(ByteUtil.bitValue(bytes[offset], 0, 3).value);
    if (output.pcModeValue.value == 0) {
      output.pcMode = Mode.idle;
    } else if (output.pcModeValue.value == 1) {
      output.pcMode = Mode.working;
    } else if (output.pcModeValue.value == 2) {
      output.pcMode = Mode.sleep;
    } else if (output.pcModeValue.value == 3) {
      output.pcMode = Mode.locked;
    }
    output.lockState = output.pcMode == Mode.locked ? Uint4(1) : Uint4.zero;
    output.mcMode = ByteUtil.bitValue(bytes[offset], 3, 3);
    output.motorState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.chargeState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;

    output.backupBatteryState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.chargePortDetect =
        ByteUtil.toUint32(ByteUtil.bitValue(bytes[offset], 1, 3).value);
    if (output.chargePortDetect.value == 0) {
      output.chargePort = ChargePort.none;
    } else if (output.chargePortDetect.value == 1) {
      output.chargePort = ChargePort.plugged;
    } else if (output.chargePortDetect.value == 2) {
      output.chargePort = ChargePort.backupBattery;
    } else if (output.chargePortDetect.value == 3) {
      output.chargePort = ChargePort.other;
    } else if (output.chargePortDetect.value == 4) {
      output.chargePort = ChargePort.undefined;
    }
    output.chargePortOn = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.dcPortDetect = ByteUtil.bitValue(bytes[offset], 5, 3);
    offset++;

    output.dcOutputEnable = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.headlightState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.decorativeLight = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.liftedState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.tailLightState = ByteUtil.bitValue(bytes[offset], 4, 3);
    output.fanWorkState = ByteUtil.bitValue(bytes[offset], 6, 1);
    offset++;

    output.brakeState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.slowDownState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.dfuState = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 保留5bit
  }

  @override
  int length() {
    return 4;
  }
}

/// 实时故障和警告
class P6RealTimeError extends EucRealTimeError {
  P6RealTimeError(ProductModel model, VersionWrapper version)
      : super(model, version);

  Uint4 motorHall1State = Uint4.zero; // 电机霍尔1状态
  Uint4 motorHall2State = Uint4.zero; // 电机霍尔2状态
  Uint4 batteryCommLost = Uint4.zero; // 电池-驱动板通讯状态
  Uint4 batteryCrossCommLost = Uint4.zero; // 电池间通讯状态
  Uint4 tboxComm = Uint4.zero; // TBOX通讯状态
  Uint4 motorStallState = Uint4.zero; // 电机堵转状态
  Uint4 tpsComm = Uint4.zero; // 胎压传感器通信状态
  Uint4 tpsLowPressure = Uint4.zero; // 胎压传感器低压状态
  Uint4 tpsLowBattery = Uint4.zero; // 胎压传感器低电量状态
  Uint4 batteryWarningState = Uint4.zero; // 电池警告状态
  Uint4 batteryProtectState = Uint4.zero; // 电池保护状态
  Uint4 chargeOverCurrentState = Uint4.zero; // 过充保护状态
  Uint4 dcOutputOverCurrentState = Uint4.zero; // 直流输出过压保护状态
  Uint4 swCombination = Uint4.zero; // 开关组合状态
  Uint4 hwOverCurrentState = Uint4.zero; // 硬件兼容性过压状态

  @override
  void initCompact() {
    compact = _DefaultP6RealTimeError();
  }

  @override
  String toString() {
    return 'P6RealTimeError{ ${super.toString()}, riskBehaviourState: $riskBehaviourState}';
  }
}

class _DefaultP6RealTimeError<P6RealTimeError>
    extends _DefaultP6RealTimeErrorImpl {}

class _DefaultP6RealTimeErrorImpl<T extends P6RealTimeError>
    extends Compact<T> {
  @override
  void fromBytes(T output, Uint8ClampedList bytes, int offset) {
    output.originalValue = ByteUtil.bytes2Int32Le(bytes, offset);

    // 故障
    output.iPhaseSensorState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.iBusSensorState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.motorHall1State = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.motorHall2State = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.batteryState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.imuSensorState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.controllerCom1State = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.controllerCom2State = ByteUtil.bitValue(bytes[offset], 7, 1);

    offset++;
    output.bleCom1State = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.bleCom2State = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.batteryCommLost = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.batteryCrossCommLost = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.mosTempSensorState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.motorTempSensorState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.boardTempSensorState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.fanState = ByteUtil.bitValue(bytes[offset], 7, 1);

    offset++;
    output.rtcState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.externalRomState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.vBusSensorState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.vBatterySensorState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.canNotPowerOffState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.canNotChargeState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.tboxComm = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.tpsComm = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;

    output.tpsLowPressure = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.tpsLowBattery = ByteUtil.bitValue(bytes[offset], 1, 1);
    // 保留6bit

    // 警告32位
    offset++;
    output.underVoltageState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.overVoltageState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.overBusCurrentState = ByteUtil.bitValue(bytes[offset], 2, 2);
    output.lowBatteryState = ByteUtil.bitValue(bytes[offset], 4, 2);
    output.overMosTempState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.overMotorTempState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.overBoardTempState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.cpuOverTempState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.imuOverTempState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.overSpeedState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.outputSaturationState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.motorSpinState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.motorBlockState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.postureState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.riskBehaviourState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.motorNoLoadState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.noSelfTestState = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.powerKeyLongPressState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.someBatteriesNotWorkState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.batteryNotCaliState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.batteryWarningState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.batteryProtectState = ByteUtil.bitValue(bytes[offset], 7, 1);
    offset++;
    output.chargeOverCurrentState = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.dcOutputOverCurrentState = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.swCombination = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.forceDfuState = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.deviceLockState = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.hwCompatibilityState = ByteUtil.bitValue(bytes[offset], 5, 1);
    output.fanLowSpeedState = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.hwOverCurrentState = ByteUtil.bitValue(bytes[offset], 7, 1);
  }

  @override
  int length() {
    return 8;
  }
}

class P6BatteryRealTimeInfo extends AbsBatteryRealTimeInfo {
  P6SingleBatteryRealTimeInfo? _battery1;
  P6SingleBatteryRealTimeInfo? _battery2;

  P6BatteryRealTimeInfo(ProductModel model, VersionWrapper version)
      : super(model, version);

  @override
  void initCompact() {
    compact = _DefaultP6BatteryRealTimeInfo(model, version);
  }

  get battery1 {
    if (_battery1 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery1!;
  }

  get battery2 {
    if (_battery2 == null)
      throw ProtocolParseException(
          "Unexpected exception. Please call [fromBytes] to gen battery info first!");
    return _battery2!;
  }

  @override
  String toString() {
    return 'P6BatteryRealTimeInfo{_battery1: $_battery1, _battery2: $_battery2}';
  }
}

class _DefaultP6BatteryRealTimeInfo extends Compact<P6BatteryRealTimeInfo> {
  final ProductModel _model;
  final VersionWrapper _versionWrapper;

  _DefaultP6BatteryRealTimeInfo(this._model, this._versionWrapper);

  @override
  void fromBytes(
      P6BatteryRealTimeInfo output, Uint8ClampedList bytes, int offset) {
    output._battery1 = P6SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery1!.fromBytes(bytes, offset);
    offset += output._battery1!.length();
    output._battery2 = P6SingleBatteryRealTimeInfo(_model, _versionWrapper);
    output._battery2!.fromBytes(bytes, offset);
  }

  @override
  int length() {
    return 16;
  }
}

class P6SingleBatteryRealTimeInfo extends AbsBatteryRealTimeInfo {
  Uint16 voltage = Uint16.zero;
  Int16 chargeCurrent = Int16.zero;
  Int16 dischargeCurrent = Int16.zero;

  Uint4 detected = Uint4.zero;
  Uint4 enable = Uint4.zero;
  Uint4 charge = Uint4.zero;

  Uint4 errorLogic = Uint4.zero;
  Uint4 errorSignal = Uint4.zero;
  Uint4 errorVoltageSensor = Uint4.zero;
  Uint4 errorCurrentSensor = Uint4.zero;
  Uint4 errorCannotCharge = Uint4.zero;
  Uint4 batteryWarning = Uint4.zero;
  Uint4 batteryProtect = Uint4.zero;
  Uint4 batteryError = Uint4.zero;

  P6SingleBatteryRealTimeInfo(ProductModel model, VersionWrapper version)
      : super(model, version);

  @override
  void initCompact() {
    compact = _DefaultP6SingleBatteryRealTimeInfo();
  }

  @override
  String toString() {
    return 'P6SingleBatteryRealTimeInfo{voltage: $voltage, chargeCurrent: $chargeCurrent, dischargeCurrent: $dischargeCurrent, detected: $detected, enable: $enable, charge: $charge, errorLogic: $errorLogic, errorSignal: $errorSignal, errorVoltageSensor: $errorVoltageSensor, errorCurrentSensor: $errorCurrentSensor, errorCannotCharge: $errorCannotCharge, batteryWarning: $batteryWarning, batteryProtect: $batteryProtect, batteryError: $batteryError}';
  }
}

class _DefaultP6SingleBatteryRealTimeInfo
    extends Compact<P6SingleBatteryRealTimeInfo> {
  @override
  void fromBytes(
      P6SingleBatteryRealTimeInfo output, Uint8ClampedList bytes, int offset) {
    output.voltage = ByteUtil.bytes2Uint16Le(bytes, offset);
    offset += 2;
    output.chargeCurrent = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;
    output.dischargeCurrent = ByteUtil.bytes2Int16Le(bytes, offset);
    offset += 2;

    output.detected = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.enable = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.charge = ByteUtil.bitValue(bytes[offset], 2, 1);
    // 剩余3bit保留
    output.errorLogic = ByteUtil.bitValue(bytes[offset], 6, 1);
    output.errorSignal = ByteUtil.bitValue(bytes[offset], 7, 1);

    offset++;

    output.errorVoltageSensor = ByteUtil.bitValue(bytes[offset], 0, 1);
    output.errorCurrentSensor = ByteUtil.bitValue(bytes[offset], 1, 1);
    output.errorCannotCharge = ByteUtil.bitValue(bytes[offset], 2, 1);
    output.batteryWarning = ByteUtil.bitValue(bytes[offset], 3, 1);
    output.batteryProtect = ByteUtil.bitValue(bytes[offset], 4, 1);
    output.batteryError = ByteUtil.bitValue(bytes[offset], 5, 1);
    // 剩余2bit保留
  }

  @override
  int length() {
    return 8;
  }
}